home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / uae / uae-0.4.3 / memory.c < prev    next >
C/C++ Source or Header  |  1998-01-20  |  9KB  |  366 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * Memory management
  5.   *
  6.   * (c) 1995 Bernd Schmidt
  7.   */
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12.  
  13. #include "config.h"
  14. #include "amiga.h"
  15. #include "options.h"
  16. #include "memory.h"
  17. #include "custom.h"
  18. #include "cia.h"
  19. #include "ersatz.h"
  20.  
  21. bool buserr;
  22.  
  23. lget_func do_lget[256];
  24. wget_func do_wget[256];
  25. bget_func do_bget[256];
  26. lput_func do_lput[256];
  27. wput_func do_wput[256];
  28. bput_func do_bput[256];
  29. xlate_func do_xlateaddr[256];
  30. check_func do_check[256];
  31.  
  32. /* Default memory access functions */
  33.  
  34. bool default_check(CPTR a, ULONG b)
  35. {
  36.     return false;
  37. }
  38.  
  39. UWORD *default_xlate(CPTR a)
  40. {
  41.     fprintf(stderr, "Your Amiga program just did something terribly stupid\n");
  42.     return 0;
  43. }
  44.  
  45. /* Chip memory */
  46.  
  47. static UWORD chipmemory[chipmem_size/2];
  48.  
  49. static ULONG chipmem_lget(CPTR) REGPARAM;
  50. static UWORD chipmem_wget(CPTR) REGPARAM;
  51. static UBYTE chipmem_bget(CPTR) REGPARAM;
  52. static void  chipmem_lput(CPTR, ULONG) REGPARAM;
  53. static void  chipmem_wput(CPTR, UWORD) REGPARAM;
  54. static void  chipmem_bput(CPTR, UBYTE) REGPARAM;
  55. static bool  chipmem_check(CPTR addr, ULONG size) REGPARAM;
  56. static UWORD *chipmem_xlate(CPTR addr) REGPARAM;
  57.  
  58. ULONG chipmem_lget(CPTR addr)
  59. {
  60.     addr -= chipmem_start & (chipmem_size-1);
  61.     addr &= chipmem_size-1;
  62.     return ((ULONG)chipmemory[addr >> 1] << 16) | chipmemory[(addr >> 1)+1];
  63. }
  64.  
  65. UWORD chipmem_wget(CPTR addr)
  66. {
  67.     addr -= chipmem_start & (chipmem_size-1);
  68.     addr &= chipmem_size-1;
  69.     return chipmemory[addr >> 1];
  70. }
  71.  
  72. UBYTE chipmem_bget(CPTR addr)
  73. {
  74.     addr -= chipmem_start & (chipmem_size-1);
  75.     addr &= chipmem_size-1;
  76.     return chipmemory[addr >> 1] >> (addr & 1 ? 0 : 8);
  77. }
  78.  
  79. void chipmem_lput(CPTR addr, ULONG l)
  80. {
  81.     addr -= chipmem_start & (chipmem_size-1);
  82.     addr &= chipmem_size-1;
  83.     chipmemory[addr >> 1] = l >> 16;
  84.     chipmemory[(addr >> 1)+1] = (UWORD)l;
  85. }
  86.  
  87. void chipmem_wput(CPTR addr, UWORD w)
  88. {
  89.     addr -= chipmem_start & (chipmem_size-1);
  90.     addr &= chipmem_size-1;
  91.     chipmemory[addr >> 1] = w;
  92. }
  93.  
  94. void chipmem_bput(CPTR addr, UBYTE b)
  95. {
  96.     addr -= chipmem_start & (chipmem_size-1);
  97.     addr &= chipmem_size-1;
  98.     if (!(addr & 1)) {
  99.     chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff) | (((UWORD)b) << 8);
  100.     } else {
  101.     chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff00) | b;
  102.     }
  103. }
  104.  
  105. bool chipmem_check(CPTR addr, ULONG size)
  106. {
  107.     addr -= chipmem_start & (chipmem_size-1);
  108.     addr &= chipmem_size-1;
  109.     return (addr + size) < chipmem_size;
  110. }
  111.  
  112. UWORD *chipmem_xlate(CPTR addr)
  113. {
  114.     addr -= chipmem_start & (chipmem_size-1);
  115.     addr &= chipmem_size-1;
  116.     return chipmemory + (addr >> 1);
  117. }
  118.  
  119. /* Slow memory */
  120.  
  121. static UWORD *bogomemory;
  122.  
  123. static ULONG bogomem_lget(CPTR) REGPARAM;
  124. static UWORD bogomem_wget(CPTR) REGPARAM;
  125. static UBYTE bogomem_bget(CPTR) REGPARAM;
  126. static void  bogomem_lput(CPTR, ULONG) REGPARAM;
  127. static void  bogomem_wput(CPTR, UWORD) REGPARAM;
  128. static void  bogomem_bput(CPTR, UBYTE) REGPARAM;
  129. static bool  bogomem_check(CPTR addr, ULONG size) REGPARAM;
  130. static UWORD *bogomem_xlate(CPTR addr) REGPARAM;
  131.  
  132. ULONG bogomem_lget(CPTR addr)
  133. {
  134.     addr -= bogomem_start & (bogomem_size-1);
  135.     addr &= bogomem_size-1;
  136.     return ((ULONG)bogomemory[addr >> 1] << 16) | bogomemory[(addr >> 1)+1];
  137. }
  138.  
  139. UWORD bogomem_wget(CPTR addr)
  140. {
  141.     addr -= bogomem_start & (bogomem_size-1);
  142.     addr &= bogomem_size-1;
  143.     return bogomemory[addr >> 1];
  144. }
  145.  
  146. UBYTE bogomem_bget(CPTR addr)
  147. {
  148.     addr -= bogomem_start & (bogomem_size-1);
  149.     addr &= bogomem_size-1;
  150.     return bogomemory[addr >> 1] >> (addr & 1 ? 0 : 8);
  151. }
  152.  
  153. void bogomem_lput(CPTR addr, ULONG l)
  154. {
  155.     addr -= bogomem_start & (bogomem_size-1);
  156.     addr &= bogomem_size-1;
  157.     bogomemory[addr >> 1] = l >> 16;
  158.     bogomemory[(addr >> 1)+1] = (UWORD)l;
  159. }
  160.  
  161. void bogomem_wput(CPTR addr, UWORD w)
  162. {
  163.     addr -= bogomem_start & (bogomem_size-1);
  164.     addr &= bogomem_size-1;
  165.     bogomemory[addr >> 1] = w;
  166. }
  167.  
  168. void bogomem_bput(CPTR addr, UBYTE b)
  169. {
  170.     addr -= bogomem_start & (bogomem_size-1);
  171.     addr &= bogomem_size-1;
  172.     if (!(addr & 1)) {
  173.     bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff) | (((UWORD)b) << 8);
  174.     } else {
  175.     bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff00) | b;
  176.     }
  177. }
  178.  
  179. bool bogomem_check(CPTR addr, ULONG size)
  180. {
  181.     addr -= bogomem_start & (bogomem_size-1);
  182.     addr &= bogomem_size-1;
  183.     return (addr + size) < bogomem_size;
  184. }
  185.  
  186. UWORD *bogomem_xlate(CPTR addr)
  187. {
  188.     addr -= bogomem_start & (bogomem_size-1);
  189.     addr &= bogomem_size-1;
  190.     return bogomemory + (addr >> 1);
  191. }
  192.  
  193. /* Kick memory */
  194.  
  195. static int zkickfile = 0;
  196. static UWORD kickmemory[kickmem_size/2];
  197.  
  198. static ULONG kickmem_lget(CPTR) REGPARAM;
  199. static UWORD kickmem_wget(CPTR) REGPARAM;
  200. static UBYTE kickmem_bget(CPTR) REGPARAM;
  201. static void  kickmem_lput(CPTR, ULONG) REGPARAM;
  202. static void  kickmem_wput(CPTR, UWORD) REGPARAM;
  203. static void  kickmem_bput(CPTR, UBYTE) REGPARAM;
  204. static bool  kickmem_check(CPTR addr, ULONG size) REGPARAM;
  205. static UWORD *kickmem_xlate(CPTR addr) REGPARAM;
  206.  
  207. ULONG kickmem_lget(CPTR addr)
  208. {
  209.     addr -= kickmem_start & (kickmem_size-1);
  210.     addr &= kickmem_size-1;
  211.     return ((ULONG)kickmemory[addr >> 1] << 16) | kickmemory[(addr >> 1)+1];
  212. }
  213.  
  214. UWORD kickmem_wget(CPTR addr)
  215. {
  216.     addr -= kickmem_start & (kickmem_size-1);
  217.     addr &= kickmem_size-1;
  218.     return kickmemory[addr >> 1];
  219. }
  220.  
  221. UBYTE kickmem_bget(CPTR addr)
  222. {
  223.     addr -= kickmem_start & (kickmem_size-1);
  224.     addr &= kickmem_size-1;
  225.     return kickmemory[addr >> 1] >> (addr & 1 ? 0 : 8);
  226. }
  227.  
  228. void kickmem_lput(CPTR a, ULONG b)
  229. {
  230. }
  231.  
  232. void kickmem_wput(CPTR a, UWORD b)
  233. {
  234. }
  235.  
  236. void kickmem_bput(CPTR a, UBYTE b)
  237. {
  238. }
  239.  
  240. bool kickmem_check(CPTR addr, ULONG size)
  241. {
  242.     addr -= kickmem_start & (kickmem_size-1);
  243.     addr &= kickmem_size-1;
  244.     return (addr + size) < kickmem_size;
  245. }
  246.  
  247. UWORD *kickmem_xlate(CPTR addr)
  248. {
  249.     addr -= kickmem_start & (kickmem_size-1);
  250.     addr &= kickmem_size-1;
  251.     return kickmemory + (addr >> 1);
  252. }
  253.  
  254. static bool load_kickstart(void)
  255. {
  256.     int i;
  257.     ULONG cksum = 0, prevck = 0;
  258.     unsigned char buffer[8];
  259.     
  260.     FILE *f = fopen("kick.rom", "rb");
  261.     
  262.     if (f == NULL) {    
  263.         fprintf(stderr, "No Kickstart ROM found.\n");
  264.     return false;
  265.     }
  266.     
  267.     fread(buffer, 1, 8, f);
  268.     if (buffer[4] == 0 && buffer[5] == 8 && buffer[6] == 0 && buffer[7] == 0) {
  269.     fprintf(stderr, "You seem to have a ZKick file there... You probably lose.\n");
  270.     zkickfile = 1;
  271.     } else 
  272.     fseek(f, 0, SEEK_SET);
  273.     
  274.     for(i = 0; i < kickmem_size/2; i++) {
  275.     if (fread(buffer, 1, 2, f) < 2) {
  276.         if (feof(f) && i == kickmem_size/4) {
  277.         fprintf(stderr, "Warning: Kickstart is only 256K.\n");
  278.         memcpy (kickmemory + kickmem_size/4, kickmemory, kickmem_size/2);
  279.         break;
  280.         } else {
  281.         fprintf(stderr, "Error while reading Kickstart.\n");
  282.         return false;
  283.         }
  284.     }
  285.     kickmemory[i] = buffer[0]*256 + buffer[1];
  286.     }
  287.     fclose (f);
  288.     
  289.     for (i = 0; i < kickmem_size/4; i++) {
  290.     ULONG data = kickmemory[i*2]*65536 + kickmemory[i*2+1];
  291.     cksum += data;
  292.     if (cksum < prevck)
  293.         cksum++;
  294.     prevck = cksum;
  295.     }
  296.     if (cksum != 0xFFFFFFFF) {
  297.     fprintf(stderr, "Warning: Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
  298.     }
  299.     return true;
  300. }
  301.  
  302. /* Address banks */
  303.  
  304. addrbank chipmem_bank = {
  305.     chipmem_lget, chipmem_wget, chipmem_bget,
  306.     chipmem_lput, chipmem_wput, chipmem_bput,
  307.     chipmem_xlate, chipmem_check
  308. };
  309.  
  310. addrbank bogomem_bank = {
  311.     bogomem_lget, bogomem_wget, bogomem_bget,
  312.     bogomem_lput, bogomem_wput, bogomem_bput,
  313.     bogomem_xlate, bogomem_check
  314. };
  315.  
  316. addrbank kickmem_bank = {
  317.     kickmem_lget, kickmem_wget, kickmem_bget,
  318.     kickmem_lput, kickmem_wput, kickmem_bput,
  319.     kickmem_xlate, kickmem_check
  320. };
  321.  
  322. void memory_init(void)
  323. {
  324.     buserr = false;
  325.     
  326.     map_banks(chipmem_bank, 0, 256);    
  327.     map_banks(custom_bank, 0xC0, 0x20);    
  328.     map_banks(cia_bank, 0xBF, 1);
  329.     map_banks(clock_bank, 0xDC, 1);
  330.     
  331.     if (use_slow_mem && bogomem_size > 0) {
  332.     bogomemory = (UWORD *)malloc (bogomem_size);
  333.         map_banks(bogomem_bank, 0xC0, bogomem_size >> 16);
  334.     }
  335.  
  336.     map_banks(rtarea_bank, 0xF0, 1); 
  337.     rtarea_init ();
  338.     if (!load_kickstart()) {
  339.     init_ersatz_rom(kickmemory);
  340.     }
  341.     if (zkickfile)
  342.     map_banks(kickmem_bank, 0x20, 8);
  343.     
  344.     map_banks(kickmem_bank, 0xF8, 8);
  345.     if (use_fast_mem && fastmem_size > 0 && !zkickfile) {
  346.     map_banks(expamem_bank, 0xE8, 1);
  347.     expamem_init();
  348.     }
  349.         
  350. }
  351.  
  352. void map_banks(addrbank bank, int start, int size)
  353. {
  354.     int bnr;
  355.     for(bnr=start; bnr < start+size; bnr++) {
  356.     do_lget[bnr] = bank.lget;
  357.     do_wget[bnr] = bank.wget;
  358.     do_bget[bnr] = bank.bget;
  359.     do_lput[bnr] = bank.lput;
  360.     do_wput[bnr] = bank.wput;
  361.     do_bput[bnr] = bank.bput;
  362.     do_xlateaddr[bnr] = bank.xlateaddr;
  363.     do_check[bnr] = bank.check;
  364.     }
  365. }
  366.